package salary

import "reflect"

type ChangeAffiliationTransaction struct {
	ChangeEmployeeTransaction
	GetAffiliation   func() Affiliation
	RecordMembership func(employee Employee)
}

func (c *ChangeAffiliationTransaction) Change(employee Employee) {
	c.RecordMembership(employee)
	employee.Affiliation = c.GetAffiliation()
}

type ChangeMemberTransaction struct {
	ChangeEmployeeTransaction
	Dues     float64
	memberId int
}

func (c *ChangeMemberTransaction) GetAffiliation() Affiliation {
	return &UnionAffiliation{c.memberId, c.Dues, make([]ServiceCharge, 10)}
}

func (c *ChangeMemberTransaction) RecordMembership(employee Employee) {
	GetDB().AddUnionAffiliation(c.memberId, employee)
}

func GetChangeMemberTransaction(employeeId int, memberId int, dues float64) *ChangeMemberTransaction {
	c := &ChangeMemberTransaction{
		*GetChangeEmployeeTransaction(employeeId),
		dues,
		memberId,
	}
	c.ChangeEmployeeTransaction.Change = c.Change
	return c
}

//ChangeNoMemberTransaction
type ChangeNoMemberTransaction struct {
	ChangeEmployeeTransaction
}

func (c *ChangeNoMemberTransaction) GetAffiliation() Affiliation {
	return &NoAffiliation{}
}

func (c *ChangeNoMemberTransaction) RecordMembership(employee Employee) {
	affiliation := employee.Affiliation
	t := reflect.TypeOf(affiliation)

	if t == reflect.TypeOf(NoAffiliation{}) {
		return
	}
	id := affiliation.GetMemberId()
	GetDB().removeUnionAffiliation(id)
}

func GetChangeNoMemberTransaction() *ChangeNoMemberTransaction {
	c := &ChangeNoMemberTransaction{}
	c.ChangeEmployeeTransaction.Change = c.Change
	return c
}

type ChangeUnaffiliatedTransaction struct {
	ChangeAffiliationTransaction
	EmployeeId int
}

func (c *ChangeUnaffiliatedTransaction) GetAffiliation() Affiliation {
	return &NoAffiliation{}
}

func (c *ChangeUnaffiliatedTransaction) RecordMembership(employee Employee) {
	affiliation := employee.Affiliation
	if reflect.TypeOf(affiliation) == reflect.TypeOf(UnionAffiliation{}) {
		memId := affiliation.GetMemberId()
		GetDB().removeUnionAffiliation(memId)
	}
}
